package com.xzq.socket.test.day01.nio;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

/**
 * @Author xzq
 * @Description //TODO
 * @Date 2021/11/19 9:11
 * @Version 1.0.0
 **/
public abstract class ChannelAdapter extends Thread{
    private Selector selector;
    private Charset charset;

    private ChannelHandler channelHandler;

    public ChannelAdapter(Selector selector, Charset charset) {
        this.selector = selector;
        this.charset = charset;
    }

    @Override
    public void run() {
        try {
            while (true) {
                //选择器监听事件
                selector.select();
                Set<SelectionKey> keys = selector.selectedKeys();
                Iterator<SelectionKey> iter = keys.iterator();
                while (iter.hasNext()) {
                    SelectionKey key = iter.next();
                    iter.remove();
                    handlerInput(key);
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void handlerInput(SelectionKey key) {
        if (!key.isValid()) {
            return;
        }
        if (key.isAcceptable()) {
            ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
            try {
                SocketChannel sc = ssc.accept();
                sc.configureBlocking(false);
                sc.register(selector, SelectionKey.OP_READ);
                channelHandler=new ChannelHandler(sc, charset);
                channelActive(channelHandler);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (key.isReadable()) {
            SocketChannel sc = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int len = 0;
            try {
                len = sc.read(buffer);
                if (len > 0) {
                    buffer.flip();
                    byte[] bytes = new byte[buffer.remaining()];
                    buffer.get(bytes);
                    channelRead(channelHandler, new String(bytes, charset));
                }else{
                    key.channel();
                    sc.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    protected abstract void channelRead(ChannelHandler channelHandler, String s);



    protected abstract void channelActive(ChannelHandler channelHandler);



}
